package com.cysion.study.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import java.io.*;
import java.util.Map;

public class FileUtils {

    /**
     * 文件根目录
     */
    public static final String DIR_ROOT = "/.laile/";
    /**
     * 图片文件目录，优先存储在sd卡中
     */
    public static final String DIR_IMAGE = "/.laile/image/";
    /**
     * 语音文件目录，优先存储在sd卡中
     */
    public static final String DIR_VOICE = "/.laile/voice/";
    /**
     * 视频文件目录，优先存储在sd卡中
     */
    public static final String DIR_VIDEO = "/.laile/video/";
    /**
     * 其它文件目录:如apk文件，优先存储在sd卡中
     */
    public static final String DIR_OTHER = "/.laile/other/";
    /**
     * 文本文件的缓存，如附近的活动列表缓存，优先缓存在appCache中
     */
    public static final String DIR_TEXT = "/.laile/text/";


    public static String getExtension(String uri) {
        if (uri == null) {
            return null;
        }

        int dot = uri.lastIndexOf(".");
        if (dot >= 0) {
            return uri.substring(dot);
        } else {
            // No extension.
            return "";
        }
    }

    /**
     * 转换成单位
     *
     * @param length
     * @return
     */
    public static String formatFileLength(long length) {
        if (length >> 30 > 0L) {
            float sizeGb = Math.round(10.0F * (float) length / 1.073742E+009F) / 10.0F;
            return sizeGb + " GB";
        }
        if (length >> 20 > 0L) {
            return formatSizeMb(length);
        }
        if (length >> 9 > 0L) {
            float sizekb = Math.round(10.0F * (float) length / 1024.0F) / 10.0F;
            return sizekb + " KB";
        }
        return length + " B";
    }

    /**
     * 转换成Mb单位
     *
     * @param length
     * @return
     */
    public static String formatSizeMb(long length) {
        float mbSize = Math.round(10.0F * (float) length / 1048576.0F) / 10.0F;
        return mbSize + " MB";
    }


    /**
     * 检查SDCARD是否可写
     *
     * @return
     */
    public static boolean checkExternalStorageCanWrite() {
        try {
            boolean mouted = Environment.getExternalStorageState().equals(
                    Environment.MEDIA_MOUNTED);
            if (mouted) {
                boolean canWrite = new File(Environment
                        .getExternalStorageDirectory().getAbsolutePath())
                        .canWrite();
                if (canWrite) {
                    return true;
                }
            }
        } catch (Exception e) {
        }
        return false;
    }

    /**
     * 获取sd卡本app的根目录路径
     *
     * @param context
     * @return
     */
    public static String getRootDirOfSDForApp(Context context) {
        File file = new File(getRootPathOfSD(context) + DIR_ROOT);
        if (!file.exists()) {
            file.mkdirs();
        }
        return file.getAbsolutePath();
    }

    /**
     * 获取sd卡本app的根目录
     *
     * @param context
     * @return
     */
    public static File getRootDirFileOfSDForApp(Context context) {
        File file = new File(getRootPathOfSD(context) + DIR_ROOT);
        if (!file.exists()) {
            file.mkdirs();
        }
        return file;
    }


    /**
     * 根据文件名和后缀 拷贝文件
     *
     * @param fileDir
     * @param fileName
     * @param ext
     * @param buffer
     * @return
     */
    public static int copyFile(String fileDir, String fileName, String ext,
                               byte[] buffer) {
        return copyFile(fileDir, fileName + ext, buffer);
    }

    /**
     * 拷贝文件
     *
     * @param fileDir
     * @param fileName
     * @param buffer
     * @return
     */
    public static int copyFile(String fileDir, String fileName, byte[] buffer) {
        if (buffer == null) {
            return -2;
        }

        try {
            File file = new File(fileDir);
            if (!file.exists()) {
                file.mkdirs();
            }
            File resultFile = new File(file, fileName);
            if (!resultFile.exists()) {
                resultFile.createNewFile();
            }
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(
                    new FileOutputStream(resultFile, true));
            bufferedOutputStream.write(buffer);
            bufferedOutputStream.flush();
            bufferedOutputStream.close();
            return 0;

        } catch (Exception e) {
        }
        return -1;
    }

    public static String getFileExt(String fileName) {

        if (TextUtils.isEmpty(fileName)) {

            return "";
        }
        return fileName.substring(fileName.lastIndexOf(".") + 1,
                fileName.length());
    }

    /**
     * decode file length
     *
     * @param filePath
     * @return
     */
    public static int decodeFileLength(String filePath) {
        if (TextUtils.isEmpty(filePath)) {
            return 0;
        }
        File file = new File(filePath);
        if (!file.exists()) {
            return 0;
        }
        return (int) file.length();
    }

    @SuppressLint("NewApi")
    public static Bitmap createVideoThumbnail(String filePath) {
        Bitmap bitmap = null;
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
        try {
            // retriever.setMode(MediaMetadataRetriever.);
            retriever.setDataSource(filePath);

            bitmap = retriever.getFrameAtTime(1000);

        } catch (Exception ex) {

        } finally {
            try {
                retriever.release();

            } catch (RuntimeException ex) {
            }

        }
        return bitmap;

    }

    /**
     * @param filePath
     * @param seek
     * @param length
     * @return
     */
    public static byte[] readFlieToByte(String filePath, int seek, int length) {
        if (TextUtils.isEmpty(filePath)) {
            return null;
        }
        File file = new File(filePath);
        if (!file.exists()) {
            return null;
        }
        if (length == -1) {
            length = (int) file.length();
        }

        try {
            RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
            byte[] bs = new byte[length];
            randomAccessFile.seek(seek);
            randomAccessFile.readFully(bs);
            randomAccessFile.close();
            return bs;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取文件扩展名
     *
     * @param fileName
     * @return
     */
    public static String getFileFormat(String fileName) {
        if (TextUtils.isEmpty(fileName))
            return "";

        int point = fileName.lastIndexOf('.');
        return fileName.substring(point + 1);
    }


    /**
     * 获取图片文件的目录
     *
     * @param context
     * @return
     */
    public static String getImageDir(Context context) {
        File file = new File(getRootPathOfSD(context) + DIR_IMAGE);
        if (!file.exists()) {
            file.mkdirs();
        }
        return file.getAbsolutePath();
    }

    /**
     * 获取语音文件目录
     *
     * @param context
     * @return
     */
    public static String getVoiceDir(Context context) {
        File file = new File(getRootPathOfSD(context) + DIR_VOICE);
        if (!file.exists()) {
            file.mkdirs();
        }
        return file.getAbsolutePath();
    }

    /**
     * 获取视频文件目录
     *
     * @param context
     * @return
     */
    public static String getVideoDir(Context context) {
        File file = new File(getRootPathOfSD(context) + DIR_VIDEO);
        if (!file.exists()) {
            file.mkdirs();
        }
        return file.getAbsolutePath();
    }

    /**
     * 获取其它文件目录
     *
     * @param context
     * @return
     */
    public static String getOtherDir(Context context) {
        File file = new File(getRootPathOfSD(context) + DIR_OTHER);
        if (!file.exists()) {
            file.mkdirs();
        }
        return file.getAbsolutePath();
    }

    /**
     * 获取文本文件目录
     *
     * @param context
     * @return
     */
    public static String getTextDir(Context context) {
        File file = new File(getRootPathOfCache(context) + DIR_TEXT);
        if (!file.exists()) {
            file.mkdirs();
        }
        return file.getAbsolutePath();
    }

    /**
     * 优先返回sd卡的根路径，不存在sd卡时返回appCache的根路径
     *
     * @param context
     * @return
     */
    public static String getRootPathOfSD(Context context) {
        if (checkSDExists()) {
            return Environment.getExternalStorageDirectory().getAbsolutePath();
        } else {
            return context.getCacheDir().getAbsolutePath();
        }

    }

    /**
     * 返回appCache的路径
     *
     * @param context
     * @return
     */
    public static String getRootPathOfCache(Context context) {
        return context.getCacheDir().getAbsolutePath();
    }

    /**
     * 优先返回sd卡的根目录，不存在sd卡时返回appCache的根目录
     *
     * @param context
     * @return
     */
    public static File getRootFileOfSD(Context context) {
        if (checkSDExists()) {
            return Environment.getExternalStorageDirectory();
        } else {
            return context.getCacheDir();
        }

    }

    /**
     * 返回appCache的根目录
     *
     * @param context
     * @return
     */
    public static File getRootFileOfCache(Context context) {
        return context.getCacheDir();
    }

    /**
     * 检查是否安装SD卡
     *
     * @return
     */
    public static boolean checkSDExists() {
        return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
    }


    public static String getSdcardPath() {
        if (checkSDExists())
            return Environment.getExternalStorageDirectory().getAbsolutePath();
        return null;
    }


    /**
     * 检查是否安装外置的SD卡
     *
     * @return
     */
    public static boolean checkExternalSDExists() {
        Map<String, String> evn = System.getenv();
        return evn.containsKey("SECONDARY_STORAGE");
    }

    /**
     * 检查文件是否存在
     *
     * @param fileAbsolutePath 文件的绝对路径
     * @return
     */
    public static boolean checkFileExists(String fileAbsolutePath) {
        boolean status = false;
        if (!TextUtils.isEmpty(fileAbsolutePath)) {
            File file = new File(fileAbsolutePath);
            return file.exists();
        }
        return status;
    }

    /**
     * 产生新的文件名
     *
     * @return
     */
    public static String createFileName() {
        return System.currentTimeMillis() + "";
    }

    /**
     * 产生新的带后缀的文件名
     *
     * @param suffix 如".jpg"、".arm"等
     * @return
     */
    public static String createFileName(String suffix) {
        return createFileName() + suffix;
    }

    /**
     * 创建带后缀的文件
     *
     * @param suffix
     * @param context
     * @return
     */
    public static File createFileWithSuffix(String suffix, Context context) {
        File file = null;
        if (TextUtils.isEmpty(suffix)) {
//            KLog.e("suffix为空");
            return file;
        }
        // 图片
        if (".jpg".equals(suffix) || ".png".equals(suffix)) {
            file = new File(getImageDir(context) + File.separator + createFileName(suffix));
            // 音频
        } else if (".amr".equals(suffix) || ".mp3".equals(suffix) || ".pcm".equals(suffix) || ".wav".equals(suffix)) {
            file = new File(getVoiceDir(context) + File.separator + createFileName(suffix));
            // 视频
        } else if (".mp4".equals(suffix)) {
            file = new File(getVideoDir(context) + File.separator + createFileName(suffix));
            // 文本
        } else if (".text".equals(suffix)) {
            file = new File(getTextDir(context) + File.separator + createFileName(suffix));
        } else if (".apk".equals(suffix)) {
            //安装包
            file = new File(getOtherDir(context) + File.separator + createFileName(suffix));
        } else {
//            KLog.e("不支持该文件类型：" + suffix);
        }
        return file;
    }

    /**
     * 写文本文件 在Android系统中，文件保存在 /data/data/PACKAGE_NAME/files 目录下
     */
    public static void writeToData(Context context, String fileName, String content) {
        if (content == null)
            content = "";
        try {
            FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
            fos.write(content.getBytes());
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @param context
     * @param content
     * @return 文件名
     */
    public static String writeToData(Context context, String content) {
        if (content == null)
            content = "";
        String fileName = createFileName();
        try {
            FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
            fos.write(content.getBytes());
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fileName;
    }

    /**
     * 从data中读取文本文件
     *
     * @param context
     * @param fileName
     * @return
     */
    public static String readFromData(Context context, String fileName) {
        try {
            FileInputStream in = context.openFileInput(fileName);
            return readFromInputStream(in);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 从输入流中读取
     *
     * @param inStream
     * @return
     */
    public static String readFromInputStream(InputStream inStream) {
        try {
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[512];
            int length = -1;
            while ((length = inStream.read(buffer)) != -1) {
                outStream.write(buffer, 0, length);
            }
            outStream.close();
            inStream.close();
            return outStream.toString();
        } catch (IOException e) {
            Log.i("FileTest", e.getMessage());
        }
        return null;
    }


    /**
     * 获取目录文件大小
     *
     * @param dir
     * @return
     */
    public static long getDirSize(File dir) {
        if (dir == null) {
            return 0;
        }
        if (!dir.isDirectory()) {
            return 0;
        }
        long dirSize = 0;
        File[] files = dir.listFiles();
        for (File file : files) {
            if (file.isFile()) {
                dirSize += file.length();
            } else if (file.isDirectory()) {
                dirSize += getDirSize(file); // 递归调用继续统计
            }
        }
        return dirSize;
    }


    /**
     * 删除一定时间以前新建或修改的文件
     *
     * @param file
     * @param timeSpace 该方法会删除该时间以前的文件
     * @return
     */
    public static void delete(File file, long timeSpace) {

        if (file != null) {
            if (file.isFile() && file.lastModified() < timeSpace) {
                file.delete();
            } else if (file.isDirectory()) {
                File[] files = file.listFiles();
                try {
                    for (File deleteFile : files) {
                        if (deleteFile.isFile() && deleteFile.lastModified() < timeSpace) {
                            deleteFile.delete();
                        } else if (deleteFile.isDirectory()) {
                            delete(deleteFile, timeSpace);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }


}
